﻿// <copyright file="ProcessMessageActivity.cs" company="">
// Copyright (c) 2013 All Rights Reserved
// </copyright>
// <author></author>
// <date>9/22/2013 11:40:15 AM</date>
// <summary>Implements the ProcessMessageActivity Workflow Activity.</summary>
namespace DynCRMMessagingIntegration.Workflow
{
    using System;
    using System.Activities;
    using System.ServiceModel;
    using Microsoft.Xrm.Sdk;
    using Microsoft.Xrm.Sdk.Workflow;
    using Microsoft.Xrm.Sdk.Query;
    using DynCRMMessagingIntegration.Common;
    using Microsoft.Crm.Sdk.Messages;

    public sealed class ProcessMessageActivity : BaseCodeActivity
    {
        protected override void ExecuteActivity(CodeActivityContext executionContext)
        {
            Entity crmMessage = this.OrganizationService.Retrieve("gxrm_message", this.WorkflowContext.PrimaryEntityId, new ColumnSet("gxrm_body"));

            if (crmMessage.Contains("gxrm_body"))
            {
                string messageBody = crmMessage["gxrm_body"].ToString();
                this.TracingService.Trace("Message body: {0}", messageBody);
                try
                {
                    IMessageProcessor processor = MessageProcessorFactory.GetProcessor(messageBody, this.TracingService);
                    if (processor != null)
                    {
                        processor.Execute(new MessageProcessorContext()
                            {
                                WorkflowContext = this.WorkflowContext
                                ,
                                ActivityContext = executionContext
                                ,
                                OrganizationService = this.OrganizationService
                                ,
                                TracingService = this.TracingService
                            }
                        );
                        UpdateMessageStatus(crmMessage.Id, MessageStatuses.Processed, this.OrganizationService);
                    }
                    else
                        throw new InvalidPluginExecutionException("No processor was found for the current message");
                }
                catch (Exception exc)
                {
                    UpdateMessageStatus(crmMessage.Id, MessageStatuses.Error, this.OrganizationService);
                    throw new InvalidPluginExecutionException("There was an error processing the current message. Error message: " + exc.Message, exc);
                }
            }
        }

        private void UpdateMessageStatus(Guid recordId, MessageStatuses statusReason, IOrganizationService service)
        {
            SetStateRequest stateRequest = new SetStateRequest();
            stateRequest.State = new OptionSetValue(0); //Active
            stateRequest.Status = new OptionSetValue((int)statusReason);
            stateRequest.EntityMoniker = new EntityReference("gxrm_message", recordId);
            service.Execute(stateRequest);
        }   

        enum MessageStatuses
        {
            New = 1,
            Processed = 968160000,
            Error = 968160000
        }
    }
}